<script lang="ts">
import mitt from 'mitt';
import { AsyncDialogProvide } from './index';
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn';
import enUS from '@arco-design/web-vue/es/locale/lang/en-us';

zhCN.datePicker.ok = '确认';

export default {
  name: 'OpenAsyncDialog',

  provide() {
    return {
      [AsyncDialogProvide as symbol]: {
        setError: () => {
          this.loading = false;
          this.title = this.$t('settings.component.dialog.error');
        },
        autoAdjustPosition: () => {
          this.$nextTick(() => {
            this.autoAdjustPosition();
          });
        },
        setButton: (button: string, text: string) => {
          this.buttons[button] = text;
        },
        setButtons: (buttons: Record<string, never>) => {
          this.buttons = buttons;
        },
        setTitle: (text: string) => {
          this.title = text;
        },
      },
    }
  },

  data() {
    return {
      emitter: mitt(),
      visible: false,
      title: this.$t('settings.component.dialog.defaultTitle'),
      width: 600,
      buttons: {} as Record<string | number, string | boolean>,
      disabled: false,
      hideClose: false,
      loading: true,
      error: [] as string[],
      zhCN,
      enUS,
    }
  },

  computed: {
    dialogProps() {
      return {};
    },
  },

  methods: {
    bodyMounted() {
      this.emitter.emit('mounted');
    },

    // 自动调整窗体 max-height
    autoAdjustPosition() {
      const el = (this.$refs.modal as any).wrapperRef;

      const hd = el.querySelector('.arco-modal-header');
      const bd = el.querySelector('.arco-modal-body');
      const ft = el.querySelector('.arco-modal-footer');
      const height = document.documentElement.clientHeight;
      const hdHeight = hd.clientHeight;
      const ftHeight = ft.clientHeight;

      if (bd.scrollHeight + hdHeight + ftHeight + 40 > height) {
        bd.style.maxHeight = `${(height - hdHeight - ftHeight - 40)}px`;
      }
    },

    open() {
      this.visible = true;
    },

    close() {
      this.visible = false;
    },

    handleAction(button: string | number) {
      this.emitter.emit('action', button);
    },

    handleCloseAfter() {
      this.emitter.emit('close');
    },

    setError(error: string) {
      this.error.push(error);
    },
  },
}
</script>

<template>
  <AModal
    :title="title"
    :width="width"
    :mask-closable="false"
    :esc-to-close="false"
    :closable="!hideClose"
    hide-cancel
    :ok-text="$t('settings.component.dialog.button.close')"
    :ok-button-props="{ type: 'secondary' }"
    v-model:visible="visible"
    @before-close="handleAction('close')"
    @close="handleCloseAfter"
    class="open-async-dialog"
    ref="modal"
  >

    <AConfigProvider update-at-scroll :locale="$i18n.locale === 'en-US' ? enUS : zhCN">
      <OpenAsyncDialogBody v-bind="dialogProps" @vue:mounted="bodyMounted" ref="body" />
    </AConfigProvider>

    <AResult status="error" :title="$t('settings.component.dialog.error')" v-if="error.length">
      <div class="whitespace-pre-wrap text-center">{{ error.join('\n') }}</div>
    </AResult>
    <ASpin v-else-if="loading" />

    <template #footer>
      <template v-if="Array.isArray(buttons)">
        <AButton
          v-for="(item, index) in buttons"
          :key="index"
          :type="item.name == 'ok' || item.name == 'yes' ? 'primary' : 'secondary'"
          :disabled="disabled"
          @click="handleAction(item.name)"
        >
          {{ item.text }}
        </AButton>
      </template>
      <template v-else>
        <template v-for="(item, index) in buttons" :key="index">
          <AButton
            :type="index == 'ok' || index == 'yes' ? 'primary' : 'secondary'"
            :disabled="disabled"
            @click="handleAction(index)"
            v-if="item !== false"
          >
            {{ item }}
          </AButton>
        </template>
      </template>
    </template>
  </AModal>
</template>

<style lang="scss">
.open-async-dialog {
  .open-upload {
    .arco-upload-list.arco-upload-list-type-picture {
      .arco-upload-list-item {
        .arco-upload-list-item-operation {
          bottom: 0;
        }
      }
    }
  }
}
</style>
